#include "protocol_impl.h"
#include "utils_log.h"
#include "record_command_handler.h"

namespace El {
namespace Protocol {

IProtocolPtr IProtocol::GetCustomInstance(std::string instanceName)
{
    static std::mutex g_customInstanceMutex;
    static std::unordered_map<std::string, IProtocolPtr> instances;

    std::lock_guard<std::mutex> lock(g_customInstanceMutex);
    auto it = instances.find(instanceName);
    if (it == instances.end()) {
        it = instances.emplace(instanceName, std::make_shared<ProtocolImpl>()).first;
    }
    return it->second;
}

ProtocolImpl::ProtocolImpl()
{
    // 注册认证相关方法
    auth_processor_ = std::make_unique<AuthProcessor>();
    auth_processor_->RegisterMethodHandlers(method_handlers_);

    // 注册设备协议相关方法
    device_protocol_processor_ = std::make_unique<DeviceCommandHandler>();
    device_protocol_processor_->RegisterMethodHandlers(method_handlers_);

    // 注册固件升级相关方法
    firmware_upgrade_processor_ = std::make_unique<FirmwareUpgradeHandler>();
    firmware_upgrade_processor_->RegisterMethodHandlers(method_handlers_);

    // 注册模型管理相关方法
    model_handler_ = std::make_unique<ModelHandler>();
    model_handler_->RegisterMethodHandlers(method_handlers_);

    // 注册音频管理相关方法
    audio_command_handler_ = std::make_unique<AudioCommandHandler>();
    audio_command_handler_->RegisterMethodHandlers(method_handlers_);

    // 注册网络协议相关方法
    net_command_handler_ = std::make_unique<NetCommandHandler>();
    net_command_handler_->RegisterMethodHandlers(method_handlers_);

    // 注册用户管理相关方法
    user_command_handler_ = std::make_unique<UserCommandHandler>();
    user_command_handler_->RegisterMethodHandlers(method_handlers_);

    // 注册串口管理相关方法
    serial_command_handler_ = std::make_unique<SerialCommandHandler>();
    serial_command_handler_->RegisterMethodHandlers(method_handlers_);

    // 注册录像管理相关方法
    record_command_handler_ = std::make_unique<RecordCommandHandler>();
    record_command_handler_->RegisterMethodHandlers(method_handlers_);

    // 注册通用配置相关方法
    config_command_handler_ = std::make_unique<ConfigCommandHandler>();
    config_command_handler_->RegisterMethodHandlers(method_handlers_);

    // 注册发现服务相关方法
    discovery_command_handler_ = std::make_unique<DiscoveryCommandHandler>();
    discovery_command_handler_->RegisterMethodHandlers(method_handlers_);
}

bool ProtocolImpl::HandleMessage(std::string &id, std::string &method, nlohmann::json &params, nlohmann::json &response)
{
    std::string params_str = params.dump(4);
    if (params_str.length() > 100) {
        params_str = params_str.substr(0, 100) + "...";
    }
    EL_DEBUG("id: {}, method: {}, params: {}", id, method, params_str.c_str());

    // 查找对应的方法处理器
    auto handler_it = method_handlers_.find(method);
    if (handler_it == method_handlers_.end()) {
        response = CreateErrorResponse(id, -32601, "Method not found");
        EL_ERROR("Method not found: {}", method);
        return false;
    }

    // 调用方法处理器
    response = handler_it->second(id, params);
    EL_DEBUG("response: {}", response.dump(4).c_str());
    return true;
}

bool ProtocolImpl::ParseRequest(const std::string &message,
                                std::string &id,
                                std::string &method,
                                nlohmann::json &params)
{
    nlohmann::json request;
    auto result = nlohmann::json::parse(message, nullptr, false);
    if (result.is_discarded()) {
        EL_WARN("Failed to parse JSON message: {}", message);
        return false;
    }
    request = std::move(result);

    // 检查必需字段
    if (!request.contains("method") || !request["method"].is_string()) {
        EL_ERROR("Invalid request format: missing or invalid method field");
        return false;
    }

    // 获取请求字段
    method = request["method"].get<std::string>();

    // ID可能是字符串或数字
    if (request.contains("id")) {
        if (request["id"].is_string()) {
            id = request["id"].get<std::string>();
        } else if (request["id"].is_number()) {
            id = std::to_string(request["id"].get<int>());
        } else {
            EL_ERROR("Invalid request format: invalid id field type");
            return false;
        }
    } else {
        id = ""; // 通知类消息可能没有ID
    }

    // 获取参数，如果没有则为空对象
    if (request.contains("params")) {
        if (!request["params"].is_object() && !request["params"].is_array()) {
            EL_ERROR("Invalid request format: params must be an object");
            return false;
        }
        params = request["params"];
    } else {
        params = nlohmann::json::object();
    }

    return true;
}

bool ProtocolImpl::ParseResponse(const std::string &message, std::string &id, nlohmann::json &result)
{
    nlohmann::json response;
    auto parsed = nlohmann::json::parse(message, nullptr, false);
    if (parsed.is_discarded()) {
        EL_WARN("Failed to parse JSON response: {}", message);
        return false;
    }
    response = std::move(parsed);

    // 检查是否包含id字段
    if (!response.contains("id")) {
        EL_ERROR("Invalid response format: missing id field");
        return false;
    }

    // 获取ID
    if (response["id"].is_string()) {
        id = response["id"].get<std::string>();
    } else if (response["id"].is_number()) {
        id = std::to_string(response["id"].get<int>());
    } else {
        EL_ERROR("Invalid response format: invalid id field type");
        return false;
    }

    // 检查响应类型：成功响应包含result字段，错误响应包含error字段
    if (response.contains("result")) {
        result = response["result"];
        return true;
    } else if (response.contains("error")) {
        result = response["error"]; // 错误信息也通过result返回
        EL_WARN("Received error response: {}", result.dump());
        return false;
    } else {
        EL_ERROR("Invalid response format: missing result or error field");
        return false;
    }
}

std::string ProtocolImpl::CreateRequest(const std::string &id, const std::string &method, const nlohmann::json &params)
{
    nlohmann::json request = {{"id", id}, {"method", method}};

    if (params != nullptr) {
        request["params"] = params;
    } else {
        request["params"] = nlohmann::json::object();
    }

    return request.dump(4);
}

std::string ProtocolImpl::CreateErrorResponse(const std::string &id,
                                              int code,
                                              const std::string &message,
                                              const nlohmann::json &data)
{
    nlohmann::json error = {{"code", code}, {"message", message}};

    if (data != nullptr) {
        error["data"] = data;
    }

    nlohmann::json response = {{"id", id}, {"error", error}};

    return response.dump(4);
}

} // namespace Protocol
} // namespace El
